/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package logic;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 *
 * @author Kateryna_Reznik
 */
public class TestModuleLoader extends ClassLoader{
    private java.util.Map classesHash= new java.util.HashMap();
    public final String[] classPath;
    public TestModuleLoader( String[] classPath ) {
        //ways to find class
        this.classPath= classPath;
   }
 
    protected synchronized Class loadClass( String name,boolean resolve ) throws ClassNotFoundException{
        Class result= findClass( name );
        if ( resolve ) {
            resolveClass( result );
        }
        return result;
   }
   protected Class findClass( String name ) throws ClassNotFoundException {
        
        Class result= (Class)classesHash.get(name);
        if (result!=null) {
            System.out.println("% Class "+name+" found in cache");
            return result;
        }
        
        File file = findFile(name.replace('.','/'),".class");
        //logic.TestModule -> logic/MyClass.class
        System.out.println("% Class "+name+( file == null?"":" found in "+file));
         
        if ( file == null) {
            //if file is not found, load it by system loader
             return findSystemClass( name ); 
        }
        
        try {
            byte[] classBytes= loadFileAsBytes( file );
            result= defineClass(name,classBytes,0,classBytes.length);
        } 
        catch ( IOException e ) {
            throw new ClassNotFoundException("Cannot load class "+name+": "+e);
        } 
        catch ( ClassFormatError e ) {
            throw new ClassNotFoundException("Format of class file incorrect for class "+name+": "+e);
        }
        
        classesHash.put(name,result);
        return result;
    }
 
    @Override
    protected java.net.URL findResource(String name) {
 
        File file = findFile(name,"");
    
        if ( file == null ){ 
            return null;
        }
        
        try {
            return file.toURL();
        } 
        catch(java.net.MalformedURLException e) {
            return null;
        }
    }
 
    private File findFile(String name, String extension) {
  
        for (int k=0; k<classPath.length; k++) {
             File file = new File((new File(classPath[k])).getPath()+File.separatorChar+name.replace('/',File.separatorChar)+extension);
             if ( file.exists() ){ 
                 return file;
             }
        }
        
        return null;
    }
 
    public static byte[] loadFileAsBytes( File file ) throws IOException
    {
        byte[] result = new byte[(int)file.length()];
        FileInputStream fInputStream = new FileInputStream(file);
        
        try {
          fInputStream.read(result,0,result.length);
          
        } finally {
            try {
                fInputStream.close();
            } 
            catch (Exception e) {
            }
        }
        return result;
    }
}
